package com.ht.api.task.ad;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;

import javax.sql.DataSource;

import com.ht.api.business.ad.PlanHelper;
import com.ht.api.db.Db;
import com.ht.api.db.DbConfig;
import com.ht.api.db.DbList;
import com.ht.api.db.Entity;
import com.ht.api.db.StreamLoadConfig;
import com.ht.api.db.task.HtTaskExecutor;
import com.ht.api.db.task.Plan;
import com.ht.api.db.task.TaskHandler;
import com.ht.api.open.OpenUtil;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 获取客户朋友圈发表后的可见客户列表
 */
@Slf4j
public class PullMomentVisibleTask implements TaskHandler {

    /** 接口ID：获取客户朋友圈发表后的可见客户列表 */
    protected static final long API_ID = 1901104930509426688L;

	@Override
	public String getName() {
		return "获取客户朋友圈发表后的可见客户列表";
	}

    @Override
    public boolean handler(JSONObject requestParam, String groupId, long taskId) {
        long tenantId = requestParam.getLong("tenant_id");
        DataSource ds = DbConfig.useTenantDb(tenantId);
        StreamLoadConfig config = DbConfig.useTenantSLC(tenantId);


        String adTaskGroupId = requestParam.getStr("ad_task_group_id");

        String momentId = requestParam.getStr("moment_id");
        String userid = requestParam.getStr("userid");
        String appid = requestParam.getStr("appid");

        JSONObject param = JSONUtil.createObj();
        param.set("moment_id", momentId);
        param.set("userid", userid);
        param.set("limit", 5000);

        String str = OpenUtil.call(appid, API_ID, param);
        JSONObject result = JSONUtil.parseObj(str);

        if (result.getInt("errcode") != 0) {
            return false;
        }

        JSONArray customerList = result.getJSONArray("customer_list");
        Set<String> visibleCustomer = new HashSet<>();
        for (int i = 0; i < customerList.size(); i++) {
            JSONObject customer = customerList.getJSONObject(i);
            visibleCustomer.add(customer.getStr("external_userid"));
        }

        Entity adTaskGroup = Db.createSqlParser("ad_task_group").where("main_id", adTaskGroupId).findOne(ds);
        DbList taskList = Db.createSqlParser("ad_user_task").select("main_id,touch_id,openid,plan_id,ad_id,creative_id,ad_type,act_time,context").where("ad_task_group_id", adTaskGroupId).query(ds);

        String creativeId = adTaskGroup.getStr("creative_id");
        Entity creative = Db.createSqlParser("creative").where("main_id", creativeId).findOne(ds);

        JSONArray materials = creative.getJSONArray("material");

        Map<String, List<Entity>> linkRelationMap = new HashMap<>();
        if (materials != null) {
            for (int i = 0; i < materials.size(); i++) {
                JSONObject material = materials.getJSONObject(i);
                String type = material.getStr("type");

                if (type.equals("link")) {
                    String linkId = material.getStr("link_id");
                    Entity link = Db.createSqlParser("short_link").where("main_id", linkId).findOne(ds);

                    String relationId = link.getStr("relation_id");
                    String relationTable = link.getStr("relation_type");

                    Entity linkRelation = Entity.create(relationTable);
                    linkRelation.set("main_id", relationId);
                    linkRelation.set("exposure_count", 0);

                    if (!linkRelationMap.containsKey(relationTable)) {
                        linkRelationMap.put(relationTable, new ArrayList<>());
                    }

                    linkRelationMap.get(relationTable).add(linkRelation);
                }
            }
        }

        boolean isLink = false;
        List<Entity> dataList = new CopyOnWriteArrayList<>();
        List<Runnable> taskRunList = new ArrayList<>();

        for (Entity task : taskList) {
            Entity momentCustomer = Entity.create("wx_moment_customer");
            momentCustomer.set("ad_task_group_id", adTaskGroupId);
            momentCustomer.set("userid", task.get("touch_id"));
            momentCustomer.set("openid", task.get("openid"));

            if (visibleCustomer.contains(task.getStr("openid"))) {
                isLink = true;
                momentCustomer.set("status", 1);
                task.set("status", 3);

                if (linkRelationMap.size() > 0) {
                    for (String relation : linkRelationMap.keySet()) {
                        List<Entity> linkRelationList = linkRelationMap.get(relation);
                        for (Entity entity : linkRelationList) {
                            entity.set("exposure_count", entity.getInt("exposure_count") + 1);
                        }

                        switch (relation) {
                            case "writings":
                                taskRunList.add(()->{
                                    String oneid = Db.createSqlParser("user_origin")
                                            .select("oneid").where("openid", task.get("openid")).val(ds, String.class);
                                    Entity entity = Entity.create("content_preference");
                                    entity.set("main_id", oneid);
                                    entity.set("oneid", oneid);
                                    entity.set("show_count", linkRelationList.size());
                                    dataList.add(entity);
                                });

                                break;
                        }
                    }
                }

            } else {
                momentCustomer.set("status", 2);
                task.set("status", 5);
                task.set("result_msg", "朋友圈不可见");
            }
            task.set("act_time", DateUtil.now());

            dataList.add(momentCustomer);

        }

        if (isLink) {
            for (String relation : linkRelationMap.keySet()) {
                dataList.addAll(linkRelationMap.get(relation));
            }
        }

        HtTaskExecutor.execute(taskRunList);

        dataList.addAll(taskList);

        //启动查看互动数据任务
        JSONObject pullMomentCommentParam = JSONUtil.createObj();
        pullMomentCommentParam.set("appid", appid);
        pullMomentCommentParam.set("moment_id", momentId);
        pullMomentCommentParam.set("tenant_id", tenantId);
        pullMomentCommentParam.set("userid", userid);
        pullMomentCommentParam.set("ad_task_group_id", adTaskGroupId);
        HtTaskExecutor.submitTask(pullMomentCommentParam, new PullMomentCommentTask(),
                Plan.create().setMin(60).setRate(2).setMax(60 * 60 * 3).setTimes(5, TimeUnit.DAYS));

        Db.insertBatchWithStream(config, dataList);

        HtTaskExecutor.stopTask(taskId);

        String planId = adTaskGroup.getStr("plan_id");
        if (StrUtil.isNotBlank(planId)) {
            PlanHelper.checkPlanStatus(ds, config, planId);
        }

        return true;
    }
}
